home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-01-11 | 9.7 KB | 333 lines | [TEXT/CWIE] |
- // TNetworkAcceptor.cp - Macintosh OpenTransport Network Acceptor class object
- //
- // Apple Macintosh Developer Technical Support
- // Written by: Vinne Moscaritolo
- //
- // Copyright (work in progress) Apple Computer, Inc All rights reserved.
- //
- // You may incorporate this sample code into your applications without
- // restriction, though the sample code has been provided "AS IS" and the
- // responsibility for its operation is 100% yours. However, what you are
- // not permitted to do is to redistribute the source as "DSC Sample Code"
- // after having made changes. If you're going to re-distribute the source,
- // we require that you make it clear in the source that the code was
- // descended from Apple Sample Code, but that you've made changes.
- //
-
- #include "TNetworkAcceptor.h"
- #include "TThread.h"
-
- // ---------------------------------------------------------------------------
- // NotifyProc (queue up an event)
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor OT Notifier Proc
-
- pascal void TNetworkAcceptor::NotifyProc( TNetworkAcceptor* theAcceptor, OTEventCode theEvent, OTResult theResult, void* theParam)
- {
- try
- {
- // queue event
- QUEUE_NET_EVENT( theAcceptor, theEvent, theResult, theParam);
- }
-
- catch (TNetworkException &ex)
- {
- DebugStr("\p TNetworkAcceptor::NotifyProc -- Network Exception.. ");
- }
-
- catch(TMacException &ex)
- {
- DebugStr("\p TNetworkAcceptor::NotifyProc -- Mac Exception.. ");
- }
-
- catch(...) // catch everything
- {
- DebugStr("\p TNetworkAcceptor::NotifyProc -- Other Exception.. ");
- }
-
- }
-
-
-
- // ---------------------------------------------------------------------------
- // ~TNetworkAcceptor
- // ---------------------------------------------------------------------------
- // Destructor
-
- TNetworkAcceptor::~TNetworkAcceptor()
- {
- TNetworkSession *aSess;
-
- if(fEndPoint != kOTInvalidEndpointRef) ::OTCloseProvider(fEndPoint);
- fEndPoint = kOTInvalidEndpointRef;
-
- if( fLocalAddress) delete fLocalAddress;
-
- while(aSess = (TNetworkSession*) fActiveSessions.RemoveFirst()){
- delete aSess;
- }
-
- while(aSess = (TNetworkSession*) fFreeSessions.RemoveFirst()){
- delete aSess;
- }
-
- };
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::Open( TNetworkEndpointDescriptor* )
- // ---------------------------------------------------------------------------
- // Open Network Acceptor
-
- void TNetworkAcceptor::Open(TNetworkEndpointDescriptor* theEPD)
- {
-
- // create a some thread pool for sessions
- TThread::Allocate( fPrefs.fBuildSessions, kSessionStackSpace);
-
- // save configuration info
- fEPD = theEPD;
-
- // Reset Timer
- fStats.fAcceptedSessions = 0;
- fStats.fRejectedSessions = 0;
- fStartTime.Now();
-
-
- // Setup a new endpoint
- ThrowIfOTErr( ::OTAsyncOpenEndpoint( theEPD->GetConfiguration() ,0,&fInfo,NotifyProc, this) );
- }
-
-
-
- //
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::HandleEvent (TNetworkEvent*)
- // ---------------------------------------------------------------------------
- // Network Acceptor Event Handler
-
- Boolean TNetworkAcceptor::GetStats (TAcceptorInfo* theStats)
- {
-
- if(fPending == kUnBound) return false;
-
- // update stats
- fStats.fUpTime = fStartTime.Elapsed();
- fStats.fActiveSessions = fActiveSessions.Count();
- fStats.fFreeSessions = fFreeSessions.Count();
-
- // return them
- *theStats = fStats;
- return true;
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::HandleEvent (TNetworkEvent*)
- // ---------------------------------------------------------------------------
- // Network Acceptor Event Handler
-
- void TNetworkAcceptor::HandleEvent (TNetworkEvent* theEvent)
- {
- switch ( theEvent->fEvent ) {
-
- ///// OpenEndpoint Completed
- case T_OPENCOMPLETE:
- EventOpenComplete(theEvent);
- break;
- ///// Bind Completed - Listner ready
- case T_BINDCOMPLETE:
- EventBindComplete(theEvent);
- break;
- ///// Client Attemptng Connection
- case T_LISTEN:
- EventListen(theEvent);
- break;
- ///// Handoff Completed
- case T_ACCEPTCOMPLETE:
- EventAcceptComplete(theEvent);
- break;
- ///// Client Quit
- case T_DISCONNECT:
- EventDisconnect(theEvent);
- break;
- ///// Rejection Completed
- case T_DISCONNECTCOMPLETE:
- EventDisconnectComplete(theEvent);
- break;
- ///// Winding down
- case T_UNBINDCOMPLETE:
- EventUnbindComplete(theEvent);
- break;
- ///// Sesion becomes available ***** Private Event ******
- case kSessionAvailable:
- EventSessionAvailable(theEvent);
- break;
- ////..Other ...
- default:
- EventOther(theEvent);
- break;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventOpenComplete
- // ---------------------------------------------------------------------------
- // Network Endpoint Open Completion Handler
-
- void TNetworkAcceptor::EventOpenComplete(TNetworkEvent* theEvent)
- {
- // Save endpoint ref
- fEndPoint = (EndpointRef) theEvent->fParam;
-
- // Initiate Bind
- TAddr* theAddr = fEPD->GetLocalAddress(); // get configured Addreess
- fLocalAddress = theAddr->Clone(); // create a local Address object
- theAddr->ToNetbuf(&fReqBind.addr); // fill in req Netbuf
- fLocalAddress->ToNetbuf(&fRetBind.addr); // fill in reply Netbuf
- fReqBind.qlen = fPrefs.fMaxOutStanding; // Number of Outstanding Connections
-
- ThrowIfOTErr( ::OTBind( fEndPoint, &fReqBind, &fRetBind));
-
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventSessionAvailable
- // ---------------------------------------------------------------------------
- // Handle Session becoming avail
- void TNetworkAcceptor::EventSessionAvailable(TNetworkEvent* theEvent)
- {
- TNetworkSession* theSession = (TNetworkSession*)theEvent->fParam;
-
- // If its on the Active List remove it.
- fActiveSessions.Remove(theSession);
-
- // If there is a listen pending then use this session
- if(fPending > kNonePending)
- {
- fPending--;
- DoListen(theSession);
- } else
- // If no listen is pending then save this session on freelist or recycle it
- if( fFreeSessions.Count() <= fPrefs.fMaxFreeSessions)
- fFreeSessions.Add(theSession);
- else
- delete theSession;
-
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventBindComplete
- // ---------------------------------------------------------------------------
- // Network Endpoint Bind Completion Handler
-
- void TNetworkAcceptor::EventBindComplete(TNetworkEvent* theEvent)
- {
- TBind *retAddr = (TBind *) theEvent->fParam;
-
- if(!fEPD->ValidateBind(&fReqBind,&fRetBind) ) ThrowMsg("Bind Failed");
- fStartTime.Now();
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventListen()
- // ---------------------------------------------------------------------------
- // Client Attemptng Connection
-
- void TNetworkAcceptor::EventListen(TNetworkEvent* theEvent)
- {
- TNetworkSession *aSess;
-
- // If there are free session available, then handle it else create a some spares.
- if( aSess = (TNetworkSession*) fFreeSessions.RemoveFirst())
- DoListen(aSess);
- else {
- for ( int i = 0; i < fPrefs.fBuildSessions; i++) SessionFactory();
- fPending++;
- }
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventAcceptComplete
- // ---------------------------------------------------------------------------
- // Network Endpoint Handoff Completion Handler
-
- void TNetworkAcceptor::EventAcceptComplete(TNetworkEvent* theEvent)
- {
- fStats.fAcceptedSessions++;
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventDisconnect
- // ---------------------------------------------------------------------------
- // Connecting client quit
-
- void TNetworkAcceptor::EventDisconnect(TNetworkEvent* theEvent)
- {
- fStats.fDisconSessions++;
- :: OTRcvDisconnect(fEndPoint, nil);
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventDisconnectComplete
- // ---------------------------------------------------------------------------
- // Network Endpoint Disconnect Completion Handler
-
- void TNetworkAcceptor::EventDisconnectComplete (TNetworkEvent* theEvent)
- {
- fStats.fRejectedSessions++;
- }
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventUnbindComplete( )
- // ---------------------------------------------------------------------------
- // Network Endpoint Unbind Completion Handler
-
- void TNetworkAcceptor::EventUnbindComplete (TNetworkEvent* theEvent)
- {
- fPending == kUnBound;
- }
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::EventOther
- // ---------------------------------------------------------------------------
- // Other random event
-
- void TNetworkAcceptor::EventOther(TNetworkEvent* theEvent)
- {
- if(theEvent)
- ThrowIfOTErr(noErr);
- };
-
-
-
- // ---------------------------------------------------------------------------
- // TNetworkAcceptor::DoListen(aSess)
- // ---------------------------------------------------------------------------
- void TNetworkAcceptor::DoListen(TNetworkSession *aSess)
- {
- TCall *call = aSess->GetCallInfo();
- OSStatus ErrNo;
-
- // Get Connection Information
- ThrowIfOTErr(::OTListen (fEndPoint, call)); // ***FIX THIS ****
-
- // Do you take this client....
- if( fEPD->Filter(call) )
- // Accept connection
- if((ErrNo = ::OTAccept (fEndPoint, aSess->GetEndpoint(), call)) == kOTNoError )
- {
- fActiveSessions.Add(aSess);
- return;
- }
-
- // reject connection
- ::OTSndDisconnect (fEndPoint,call);
-
- // free up unused session
- fFreeSessions.Add(aSess);
- }
-
-